﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using UnityEngine;
using Verse.Sound;

namespace Miao.Stand
{
    /// <summary>
    /// 为了查看到底为什么Verb报错
    /// </summary> 
    public class Verb_MeleeBurstAttackDamage : Verb_MeleeAttackDamage
    {
        //大冷却是Stance_Cooldown行为来设置的
        protected override int ShotsPerBurst => verbProps.burstShotCount;

        //public override bool TryStartCastOn(LocalTargetInfo castTarg, LocalTargetInfo destTarg, bool surpriseAttack = false, bool canHitNonTargetPawns = true, bool preventFriendlyFire = false)
        //{
        //        return base.TryStartCastOn(castTarg, destTarg, surpriseAttack, canHitNonTargetPawns, preventFriendlyFire);
        //}
        public override bool Available()
        {
            return base.Available();
        }

        protected override bool TryCastShot()
        {
            //var value = this.burstShotsLeft;

            Pawn casterPawn = CasterPawn;
            if (!casterPawn.Spawned)
            {
                return false;
            }
            ////全身忙碌？？
            //if (casterPawn.stances.FullBodyBusy)
            //{
            //    return false;
            //}
            Thing thing = currentTarget.Thing;
            if (!CanHitTarget(thing))
            {
                Log.Warning(string.Concat(casterPawn, " meleed ", thing, " from out of melee position."));
            }
            casterPawn.rotationTracker.Face(thing.DrawPos);
            if (!IsTargetImmobile(currentTarget) && casterPawn.skills != null)//学习近战经验
            {
                casterPawn.skills.Learn(SkillDefOf.Melee, 200f * verbProps.AdjustedFullCycleTime(this, casterPawn));
            }
            Pawn pawn = thing as Pawn;//设置被打目标的近战仇恨
            if (pawn != null)
            {
                if (!pawn.Dead && (casterPawn.MentalStateDef != MentalStateDefOf.SocialFighting || pawn.MentalStateDef != MentalStateDefOf.SocialFighting) && (casterPawn.story == null || !casterPawn.story.traits.DisableHostilityFrom(pawn)))
                {
                    pawn.mindState.meleeThreat = casterPawn;
                    pawn.mindState.lastMeleeThreatHarmTick = Find.TickManager.TicksGame;
                }

                if ((!Stand.Settings.OraOraToDead) && pawn.Downed)
                {
                    return false;
                }
                else if (pawn.Dead)
                {

                    return false;
                }
            }
            Map map = thing.Map;
            Vector3 drawPos = thing.DrawPos;
            if (burstShotsLeft == ShotsPerBurst && tool.soundMeleeHit != null)
            {
                SoundDef soundDef = tool.soundMeleeHit;
                soundDef.PlayOneShot(new TargetInfo(thing.Position, map));//播放一次相关音效
            }                                                         //bool stopAttack;//打中了才返回ture

            if (Rand.Chance(GetNonMissChance(thing)))
            {
                if (!Rand.Chance(GetDodgeChance(thing)))
                {
                    //soundDef = ((thing.def.category != ThingCategory.Building) ? SoundHitPawn() : SoundHitBuilding());
                    if (verbProps.impactMote != null)
                    {
                        MoteMaker.MakeStaticMote(drawPos, map, verbProps.impactMote);
                    }
                    if (verbProps.impactFleck != null)
                    {
                        FleckMaker.Static(drawPos, map, verbProps.impactFleck);
                    }
                    //记录战斗笔记
                    BattleLogEntry_MeleeCombat battleLogEntry_MeleeCombat = CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesHit, alwaysShow: true);
                    //stopAttack = true;
                    DamageWorker.DamageResult damageResult = ApplyMeleeDamageToTarget(currentTarget);
                    if (pawn != null && damageResult.totalDamageDealt > 0f)
                    {
                        ApplyMeleeSlaveSuppression(pawn, damageResult.totalDamageDealt);
                    }
                    if (damageResult.stunned && damageResult.parts.NullOrEmpty())
                    {
                        Find.BattleLog.RemoveEntry(battleLogEntry_MeleeCombat);
                    }
                    else
                    {
                        damageResult.AssociateWithLog(battleLogEntry_MeleeCombat);
                        if (damageResult.deflected)//偏转攻击
                        {
                            battleLogEntry_MeleeCombat.RuleDef = maneuver.combatLogRulesDeflect;
                            battleLogEntry_MeleeCombat.alwaysShowInCompact = false;//总是以紧凑的形式展示
                        }
                    }
                }
                else
                {
                    //stopAttack = false;
                    //soundDef = SoundDodge(thing);
                    MoteMaker.ThrowText(drawPos, map, "TextMote_Dodge".Translate(), 1.9f);
                    CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesDodge, alwaysShow: false);
                }
            }
            else
            {
                //stopAttack = false;
                //soundDef = SoundMiss();//没打中
                CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesMiss, alwaysShow: false);
            }

            if (casterPawn.Spawned)
            {
                casterPawn.Drawer.Notify_MeleeAttackOn(thing);//开始近战颤动
            }
            if (pawn != null && !pawn.Dead && pawn.Spawned)
            {
                pawn.stances.StaggerFor(95);//被攻击目标螨姗而行设置
            }
            if (casterPawn.Spawned)
            {
                casterPawn.rotationTracker.FaceCell(thing.Position);
            }
            if (casterPawn.caller != null)
            {
                casterPawn.caller.Notify_DidMeleeAttack();
            }
            //以后可以加个欧拉打飞

            return true;
        }



        private float GetNonMissChance(LocalTargetInfo target)
        {
            if (surpriseAttack)
            {
                return 1f;
            }
            if (IsTargetImmobile(target))
            {
                return 1f;
            }
            float num = CasterPawn.GetStatValue(StatDefOf.MeleeHitChance);
            if (ModsConfig.IdeologyActive && target.HasThing)
            {
                if (DarknessCombatUtility.IsOutdoorsAndLit(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeHitChanceOutdoorsLitOffset);
                }
                else if (DarknessCombatUtility.IsOutdoorsAndDark(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeHitChanceOutdoorsDarkOffset);
                }
                else if (DarknessCombatUtility.IsIndoorsAndDark(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeHitChanceIndoorsDarkOffset);
                }
                else if (DarknessCombatUtility.IsIndoorsAndLit(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeHitChanceIndoorsLitOffset);
                }
            }
            return num;
        }

        private float GetDodgeChance(LocalTargetInfo target)
        {
            if (surpriseAttack)
            {
                return 0f;
            }
            if (IsTargetImmobile(target))
            {
                return 0f;
            }
            Pawn pawn = target.Thing as Pawn;
            if (pawn == null)
            {
                return 0f;
            }
            Stance_Busy stance_Busy = pawn.stances.curStance as Stance_Busy;
            if (stance_Busy != null && stance_Busy.verb != null && !stance_Busy.verb.verbProps.IsMeleeAttack)
            {
                return 0f;
            }
            float num = pawn.GetStatValue(StatDefOf.MeleeDodgeChance);
            if (ModsConfig.IdeologyActive && target.HasThing)
            {
                if (DarknessCombatUtility.IsOutdoorsAndLit(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeDodgeChanceOutdoorsLitOffset);
                }
                else if (DarknessCombatUtility.IsOutdoorsAndDark(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeDodgeChanceOutdoorsDarkOffset);
                }
                else if (DarknessCombatUtility.IsIndoorsAndDark(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeDodgeChanceIndoorsDarkOffset);
                }
                else if (DarknessCombatUtility.IsIndoorsAndLit(target.Thing))
                {
                    num += caster.GetStatValue(StatDefOf.MeleeDodgeChanceIndoorsLitOffset);
                }
            }
            return num;
        }

        private bool IsTargetImmobile(LocalTargetInfo target)
        {
            Thing thing = target.Thing;
            Pawn pawn = thing as Pawn;
            if (thing.def.category == ThingCategory.Pawn && !pawn.Downed)
            {
                return pawn.GetPosture() != PawnPosture.Standing;
            }
            return true;
        }

        private bool CanApplyMeleeSlaveSuppression(Pawn targetPawn)
        {
            if (CasterPawn != null && CasterPawn.IsColonist && !CasterPawn.IsSlave && targetPawn != null && targetPawn.IsSlaveOfColony && targetPawn.health.capacities.CanBeAwake)
            {
                return !SlaveRebellionUtility.IsRebelling(targetPawn);
            }
            return false;
        }
        /// <summary>
        /// 应用近战压制
        /// </summary>
        /// <param name="targetPawn"></param>
        /// <param name="damageDealt"></param>
        private void ApplyMeleeSlaveSuppression(Pawn targetPawn, float damageDealt)
        {
            if (CanApplyMeleeSlaveSuppression(targetPawn))
            {
                SlaveRebellionUtility.IncrementMeleeSuppression(CasterPawn, targetPawn, damageDealt);
            }
        }
        private SoundDef SoundHitPawn()
        {
            if (base.EquipmentSource != null && !base.EquipmentSource.def.meleeHitSound.NullOrUndefined())
            {
                return base.EquipmentSource.def.meleeHitSound;
            }
            if (tool != null && !tool.soundMeleeHit.NullOrUndefined())
            {
                return tool.soundMeleeHit;
            }
            if (base.EquipmentSource != null && base.EquipmentSource.Stuff != null)
            {
                if (verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp)
                {
                    if (!base.EquipmentSource.Stuff.stuffProps.soundMeleeHitSharp.NullOrUndefined())
                    {
                        return base.EquipmentSource.Stuff.stuffProps.soundMeleeHitSharp;
                    }
                }
                else if (!base.EquipmentSource.Stuff.stuffProps.soundMeleeHitBlunt.NullOrUndefined())
                {
                    return base.EquipmentSource.Stuff.stuffProps.soundMeleeHitBlunt;
                }
            }
            if (CasterPawn != null && !CasterPawn.def.race.soundMeleeHitPawn.NullOrUndefined())
            {
                return CasterPawn.def.race.soundMeleeHitPawn;
            }
            return SoundDefOf.Pawn_Melee_Punch_HitPawn;
        }

        private SoundDef SoundHitBuilding()
        {
            if (base.EquipmentSource != null && !base.EquipmentSource.def.meleeHitSound.NullOrUndefined())
            {
                return base.EquipmentSource.def.meleeHitSound;
            }
            if (tool != null && !tool.soundMeleeHit.NullOrUndefined())
            {
                return tool.soundMeleeHit;
            }
            if (base.EquipmentSource != null && base.EquipmentSource.Stuff != null)
            {
                if (verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp)
                {
                    if (!base.EquipmentSource.Stuff.stuffProps.soundMeleeHitSharp.NullOrUndefined())
                    {
                        return base.EquipmentSource.Stuff.stuffProps.soundMeleeHitSharp;
                    }
                }
                else if (!base.EquipmentSource.Stuff.stuffProps.soundMeleeHitBlunt.NullOrUndefined())
                {
                    return base.EquipmentSource.Stuff.stuffProps.soundMeleeHitBlunt;
                }
            }
            if (CasterPawn != null && !CasterPawn.def.race.soundMeleeHitBuilding.NullOrUndefined())
            {
                return CasterPawn.def.race.soundMeleeHitBuilding;
            }
            return SoundDefOf.Pawn_Melee_Punch_HitBuilding;
        }

        private SoundDef SoundMiss()
        {
            if (CasterPawn != null)
            {
                if (tool != null && !tool.soundMeleeMiss.NullOrUndefined())
                {
                    return tool.soundMeleeMiss;
                }
                if (!CasterPawn.def.race.soundMeleeMiss.NullOrUndefined())
                {
                    return CasterPawn.def.race.soundMeleeMiss;
                }
            }
            return SoundDefOf.Pawn_Melee_Punch_Miss;
        }

        private SoundDef SoundDodge(Thing target)
        {
            if (target.def.race != null && target.def.race.soundMeleeDodge != null)
            {
                return target.def.race.soundMeleeDodge;
            }
            return SoundMiss();
        }
    }
}
